package com.zyht.common.excel;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DefaultExcel07Export<T> implements IExport<T>{

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Override
	public void export(List<T> list, Class<T> clazz, OutputStream os){
		if(logger.isDebugEnabled())
			logger.debug("开始执行数据导出……");
		
		if(!clazz.isAnnotationPresent(Excel.class)){
			logger.warn("请在要导出的POJO注解@Excel！！！");
			throw new RuntimeException("不允许执行导出的类……");
		}
		
		Excel excel = clazz.getAnnotation(Excel.class);
		boolean useHeader = excel.useHeader();
		
		if(null==list){
			throw new NullPointerException("无数据，已拒绝继续执行");
		}

		XSSFWorkbook book = new XSSFWorkbook();
		XSSFSheet sheet = book.createSheet();
		XSSFRow header = null;
		if(useHeader){
			header = sheet.createRow(0);
			header.setHeight((short) 400);
		}
		
		//设置样式
		XSSFCellStyle style = book.createCellStyle();
		//style.setFillForegroundColor(IndexedColors.BLUE.getIndex());
		//style.setFillBackgroundColor(IndexedColors.RED.getIndex());
		//style.setFillPattern(HSSFCellStyle.FINE_DOTS);

		//设置Excel中的边框(表头的边框)
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		style.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
		style.setBottomBorderColor(HSSFColor.BLACK.index);
		style.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
		style.setLeftBorderColor(HSSFColor.BLACK.index);
		style.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
		style.setRightBorderColor(HSSFColor.BLACK.index);
		style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
		style.setTopBorderColor(HSSFColor.BLACK.index);
		//设置字体
		XSSFFont font = book.createFont();
		font.setFontHeightInPoints((short) 14); // 字体高度
		font.setFontName(" 黑体 "); // 字体
		font.setBold(true);
		style.setFont(font);
		
		Field[] fieldArray = clazz.getDeclaredFields();
		Map<Integer, Field> map = new HashMap<Integer, Field>();
		for(Field field : fieldArray){
			if(!field.isAnnotationPresent(Column.class)){
				continue;
			}
			if(null!=header){
				Column column = field.getAnnotation(Column.class);
				int index = column.index();
				map.put(index,field);
				String label = column.label();
				XSSFCell cell = header.createCell(index);
				cell.setCellStyle(style);
				cell.setCellValue(label);
			}
		}
		
		int dataStartRowIndex = 0;
		if(useHeader){
			dataStartRowIndex = 1;
			//sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, map.size()));
		}
		
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		for(T model : list){
			XSSFRow row = sheet.createRow(dataStartRowIndex);
			map.forEach((index, field)->{
				XSSFCell cell = row.createCell(index);
				field.setAccessible(true);
				Object obj = null;
				try{
					 obj = field.get(model);
				} catch (Exception e){
					e.printStackTrace();
				}
				if(null!=obj){
					String className = obj.getClass().getName();
					if("java.lang.String".equals(className)){
						cell.setCellValue((String)obj);
					}else if("java.lang.Integer".equals(className)){
						cell.setCellValue((Integer)obj);
					}else if("java.lang.Double".equals(className)){
						cell.setCellValue((Double)obj);
					}else if("java.util.Date".equals(className)){
						Date date = (Date)obj;
						cell.setCellValue(sf.format(date));
					}else{
						cell.setCellValue(obj.toString());
					}
				}else{
					cell.setCellValue("");
				}
			});
			dataStartRowIndex++;
		}
		for(int i=0;i<sheet.getLastRowNum();i++){
			sheet.autoSizeColumn(i);
		}
		try{
			book.write(os);
			book.close();
		} catch (IOException e){
			e.printStackTrace();
		}
	}
}
